﻿namespace EFS.Common
{
	/// <summary>
	/// Class to attach mouse click events to UIElements
	/// </summary>
	// http://www.dansoltesz.com/post/2010/02/19/Silverlight-datagrid-double-click-behavior.aspx
	public class MouseClickManager
	{
		#region Private members
		private event System.Windows.Input.MouseButtonEventHandler _click;
		private event System.Windows.Input.MouseButtonEventHandler _doubleClick;
		#endregion

		#region Constructor
		/// <summary>
		/// Initializes a new instance of the <see cref="MouseClickManager"/> class.
		/// </summary>
		/// <param name="control">The control.</param>
		public MouseClickManager(int doubleClickTimeout)
		{
			this.Clicked = false;
			this.DoubleClickTimeout = doubleClickTimeout;
		}
		#endregion

		#region Events
		public event System.Windows.Input.MouseButtonEventHandler Click
		{
			add { _click += value; }
			remove { _click -= value; }
		}

		public event System.Windows.Input.MouseButtonEventHandler DoubleClick
		{
			add { _doubleClick += value; }
			remove { _doubleClick -= value; }
		}

		/// <summary>
		/// Called when [click].
		/// </summary>
		/// <param name="sender">The sender.</param>
		/// <param name="e">The <see cref="System.Windows.Input.MouseButtonEventArgs"/> instance containing the event data.</param>
		private void OnClick(object sender, System.Windows.Input.MouseButtonEventArgs e)
		{
			if (_click != null)
			{
				System.Diagnostics.Debug.Assert(sender is System.Windows.Controls.Control);
				(sender as System.Windows.Controls.Control).Dispatcher.BeginInvoke(_click, sender, e);
			}
		}

		/// <summary>
		/// Called when [double click].
		/// </summary>
		/// <param name="sender">The sender.</param>
		/// <param name="e">The <see cref="System.Windows.Input.MouseButtonEventArgs"/> instance containing the event data.</param>
		private void OnDoubleClick(object sender, System.Windows.Input.MouseButtonEventArgs e)
		{
			if (_doubleClick != null)
			{
				_doubleClick(sender, e);
			}
		}

		/// <summary>
		/// Handles the click.
		/// </summary>
		/// <param name="sender">The sender.</param>
		/// <param name="e">The <see cref="System.Windows.Input.MouseButtonEventArgs"/> instance containing the event data.</param>
		public void HandleClick(object sender, System.Windows.Input.MouseButtonEventArgs e)
		{
			lock (this)
			{
				if (this.Clicked)
				{
					this.Clicked = false;
					OnDoubleClick(sender, e);
				}
				else
				{
					this.Clicked = true;
					System.Threading.ParameterizedThreadStart threadStart = new System.Threading.ParameterizedThreadStart(ResetThread);
					System.Threading.Thread thread = new System.Threading.Thread(threadStart);
					thread.Start(e);
				}
			}
		}
		#endregion

		#region Properties
		/// <summary>
		/// Gets or sets a value indicating whether this <see cref="MouseClickManager"/> is clicked.
		/// </summary>
		/// <value><c>true</c> if clicked; otherwise, <c>false</c>.</value>
		private bool Clicked { get; set; }
		/// <summary>
		/// Gets or sets the timeout.
		/// </summary>
		/// <value>The timeout.</value>
		public int DoubleClickTimeout { get; set; }
		#endregion

		#region Methods
			#region Private
		/// <summary>
		/// Resets the thread.
		/// </summary>
		/// <param name="state">The state.</param>
		private void ResetThread(object state)
		{
			System.Threading.Thread.Sleep(this.DoubleClickTimeout);

			lock (this)
			{
				if (this.Clicked)
				{
					this.Clicked = false;
					OnClick(this, (System.Windows.Input.MouseButtonEventArgs)state);
				}
			}
		}
			#endregion
		#endregion
	}

}